package main

import (
	"fmt"
	"sort"
)

// map
func main() {
	//map是引用类型
	//声明格式1 var map [keytype]valuetype
	var map1 = make(map[string]string)
	//在声明的时候不需要知道 map 的长度，map 是可以动态增长的。 未初始化的 map 的值是 nil
	map1["key1"] = "1"
	map1["key2"] = "2"
	map1["key3"] = "3"
	for key, value := range map1 {
		fmt.Println("map1:", key, value)
	}
	//声明格式2
	var map2 map[string]int //只是定义了没有指向任何地址
	map2 = map[string]int{"key1": 1, "key2": 2, "key3": 3}
	for key, value := range map2 {
		fmt.Println("map2:", key, value)
	}
	//不能使用new来创建map 永远使用make创建

	//和数组不同，map 可以根据新增的 key-value 对动态的伸缩，因此它不存在固定长度或者最大限制。但是你也可以选择标明 map 的初始容量 capacity，就像这样：make(map[keytype]valuetype, cap)

	//既然一个 key 只能对应一个 value，而 value 又是一个原始类型，那么如果一个 key 要对应多个值 我们可以用切片作为 map 的值
	//mp1 := make(map[int][]int)
	//mp2 := make(map[int]*[]int)

	//测试 map1 中是否存在 key1：
	_, ok := map1["key1"] // 如果key1存在则ok == true，否则ok为false
	println(ok)
	if _, ok := map1["key1"]; ok {
		println(ok)
	}
	for key, value := range map1 {
		fmt.Println("map1:", key, value)
	}

	//从 map1 中删除 key1 如果 key1 不存在，该操作不会产生错误
	delete(map1, "key3")

	//使用for range循环构造map
	for i, v := range map1 {
		println("第", i, "个元素为"+v)
	}

	//map的切片
	// Version A:
	items := make([]map[int]int, 2) //创建一个切片，切片长度是5
	for i := range items {
		items[i] = make(map[int]int)
		items[i][0] = 0
		items[i][1] = 1
		items[i][2] = 2
		items[i][3] = 3
	}
	var map3 = map[int]int{1: 1, 2: 2}
	items = append(items, map3)
	for i, v := range items {
		for ix, vx := range v {
			println("第", i, "个map", ix, vx)
		}
	}

	//map的排序
	//map 默认是无序的，不管是按照 key 还是按照 value 默认都不排序
	//如果你想为 map 排序，需要将 key（或者 value）拷贝到一个切片，再对切片排序

	barVal := map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
		"delta": 87, "echo": 56, "foxtrot": 12,
		"golf": 34, "hotel": 16, "indio": 87,
		"juliet": 65, "kili": 43, "lima": 98}
	fmt.Println("没有排序之前:")
	for k, v := range barVal {
		fmt.Printf("Key: %v, Value: %v / ", k, v)
	}

	//创建一个存储keys的切片
	keys := make([]string, len(barVal))
	i := 0
	for k := range barVal {
		keys[i] = k //将key一个个存入keys中
		i++
	}
	sort.Strings(keys) //在对keys排序
	println()
	fmt.Println("排序之后:")
	for _, k := range keys {
		fmt.Printf("Key: %v, Value: %v / ", k, barVal[k]) //这里使用barVal[k]来从map中获取值     %v以默认格式打印变量的值
	}

	//map中的键值对调
	//如果map 的值类型可以作为 key 且所有的 value 是唯一的，那么通过下面的方法可以简单的做到键值对调。
	barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
		"delta": 87, "echo": 56, "foxtrot": 12,
		"golf": 34, "hotel": 16, "indio": 87,
		"juliet": 65, "kili": 43, "lima": 98}

	invMap := make(map[int]string, len(barVal))
	for k, v := range barVal {
		invMap[v] = k
	}
	fmt.Println()
	fmt.Println("对调之后:")
	for k, v := range invMap {
		fmt.Printf("Key: %v, Value: %v / ", k, v)
	}
	//如果原始 value 值不唯一那么这么做肯定会出错
}
